/**
 * Copyright 2008-2009 HAN.BIFANG
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package han.bifang.gwt.client.domain.tree;

import han.bifang.gwt.client.common.EntityConstants;
import han.bifang.gwt.client.common.RequestObject;
import han.bifang.gwt.client.common.ResponseObject;
import han.bifang.gwt.client.common.TreeNodeChangeListener;
import han.bifang.gwt.client.common.TreeNodeContentListener;
import han.bifang.gwt.client.common.entity.TreeUnit;
import han.bifang.gwt.client.communicate.BifangGWTServiceAsync;
import han.bifang.gwt.client.domain.DomainConstants;
import han.bifang.gwt.client.domain.DomainMessages;

import java.util.ArrayList;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.TreeListener;

public class DomainTree extends Composite implements TreeNodeChangeListener,
		TreeListener {

	private Tree tree = null;
	private DomainMessages cons;
	private BifangGWTServiceAsync service;
	private TreeNodeContentListener listener;

	private TreeItem selected = null;

	private TreeItem state = null;

	public void setTreeNodeContentListener(TreeNodeContentListener l) {
		this.listener = l;

	}

	private AsyncCallback<ResponseObject> getDomainTreeCallback = new AsyncCallback<ResponseObject>() {
		public void onSuccess(ResponseObject res) {
			String code = res.getCode();
			if (!code.equals("0")) {
				Window.alert("There was an error: " + res.getMsg());
				return;
			}

			ArrayList ds = (ArrayList) res.getResponse();

			for (int i = 0; i < ds.size(); i++) {
				TreeUnit st = (TreeUnit) ds.get(i);
				DomainTreeItem item = new DomainTreeItem();
				item.setHTML(st.getName());
				item.setId(st.getId());
				item.setKey(st.getKey());
				item.setParentId(st.getParentId());
				item.setType(st.getType());
				item.setSubType(st.getSubType());
				item.addItem("");
				if (st.getSubType().equals(EntityConstants.TREE_DOMAIN_LOCAL)) {
					TreeItem ti = tree.getItem(0).getChild(0);
					ti.addItem(item);

				} else {
					TreeItem ti = tree.getItem(0).getChild(1);
					ti.addItem(item);

				}

			}

		}

		public void onFailure(Throwable caught) {
			Window.alert("There was an error: " + caught.toString());
		}
	};

	private AsyncCallback<ResponseObject> getTreeChildrenCallback = new AsyncCallback<ResponseObject>() {
		public void onSuccess(ResponseObject res) {
			String code = res.getCode();
			if (!code.equals("0")) {
				Window.alert("There was an error: " + res.getMsg());
			}

			ArrayList ds = (ArrayList) res.getResponse();

			for (int i = 0; i < ds.size(); i++) {
				TreeUnit st = (TreeUnit) ds.get(i);
				DomainTreeItem item = new DomainTreeItem();
				item.setHTML(st.getName());
				item.setId(st.getId());
				item.setKey(st.getKey());
				item.setParentId(st.getParentId());
				item.setType(st.getType());
				item.setSubType(st.getSubType());
				state.addItem(item);

			}
			state.setState(true, false);

		}

		public void onFailure(Throwable caught) {
			Window.alert("There was an error: " + caught.toString());
		}
	};

	public DomainTree(DomainMessages cons, BifangGWTServiceAsync service) {
		tree = new Tree();
		tree.setTitle(cons.domainTree());
		tree.addTreeListener(this);
		this.cons = cons;
		this.service = service;

		initWidget(tree);

	}

	public void onLoad() {
		DomainTreeItem root = new DomainTreeItem();

		root.setHTML(cons.domainMgmt());
		root.setSelected(true);
		root.setSubType(DomainConstants.DOMAIN_ROOT);

		selected = root;

		DomainTreeItem localDomain = new DomainTreeItem();
		localDomain.setHTML(cons.localDomain());
		localDomain.setSubType(DomainConstants.DOMAIN_LOCAL);

		DomainTreeItem remoteDomain = new DomainTreeItem();
		remoteDomain.setHTML(cons.remoteDomain());
		remoteDomain.setSubType(DomainConstants.DOMAIN_REMOTE);

		root.addItem(localDomain);
		root.addItem(remoteDomain);
		root.setState(true);

		tree.addItem(root);
		// localDomain.addItem("");
		// remoteDomain.addItem("");
		RequestObject req = new RequestObject();
		req
				.setAction("han.bifang.gwt.server.action.domain.GetDomainTreeAction");
		// Window.alert("call service");
		service.call(req, getDomainTreeCallback);
	}

	public void onUnLoad() {
		tree = new Tree();
		selected = null;
	}

	public void onAddNode(TreeItem item) {
		DomainTreeItem dt = (DomainTreeItem) item;
		if (selected == null)
			return;
		// Window.alert(dt.getSubType());
		if (dt.getSubType().equals(EntityConstants.TREE_DOMAIN_LOCAL)) {
			// tree.getItem(0).getChild(0).getChild(0).setState(false);
			tree.getItem(0).getChild(0).addItem(dt);

			// tree.getItem(0).getChild(0).getChild(0).setState(true);
			// tree.getItem(0).getChild(0).setState(true, true);

		} else if (dt.getSubType().equals(EntityConstants.TREE_DOMAIN_REMOTE)) {
			tree.getItem(0).getChild(1).addItem(dt);
		} else
			selected.addItem(item);
		

	}

	public void onModifyNode(TreeItem item) {
		if (selected == null)
			return;
		DomainTreeItem i = (DomainTreeItem) item;
		DomainTreeItem s = (DomainTreeItem) selected;

		s.setHTML(i.getHTML());
		s.setId(i.getId());
		s.setKey(i.getKey());
		s.setParentId(i.getParentId());
		s.setSubType(i.getSubType());
		s.setType(i.getType());

	}

	public void onRemoveNode(TreeItem item) {
		if (selected == null)
			return;
		selected.setSelected(false);
		TreeItem di = selected.getParentItem();
		di.removeItem(selected);
		selected = di;
		di.setSelected(true);

		// for (int i = 0, j = selected.getChildCount(); i < j; i++) {
		// DomainTreeItem c = (DomainTreeItem) selected.getChild(i);
		// if (c.getId().equals(di.getId())) {
		// selected.removeItem(c);
		// break;
		// }
		//
		// }

	}

	public void onTreeItemSelected(TreeItem item) {
		if (!item.equals(selected))
			selected.setSelected(false);
		selected = item;
		this.listener.onTreeNodeSelected(item);

	}

	public void onTreeItemStateChanged(TreeItem item) {
		boolean open = item.getState();
		DomainTreeItem i = (DomainTreeItem) item;
		// Window.alert("" + open);
		if (open) {
			
			
			if (i.getSubType().equals(DomainConstants.DOMAIN_LOCAL)
					|| i.getSubType().equals(DomainConstants.DOMAIN_REMOTE) ||
					i.getSubType().equals(DomainConstants.DOMAIN_ROOT)) {
				//Window.alert("in " + i.getSubType() + " " + open);
				item.setState(true, false);
			} else {
				//Window.alert(i.getSubType() + " " + open);
				item.removeItems();
				state = item;
				RequestObject req = new RequestObject();
				req.setRequest(i.getId());
				req
						.setAction("han.bifang.gwt.server.action.GetTreeChildrenAction");
				service.call(req, getTreeChildrenCallback);

			}
		} else {
			item.setState(false, false);

		}

	}
}
